/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gamesync;

/**
 *
 * @author trungdung
 */
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;


public class SyncDeamon {
    
    //port server
    private int port=6666;
    
    //ips
    private List<String> IPs=new ArrayList();
    
    //Khoi tao object giai ma data
    Encrypter en;
    
    //Tao Queue chua Query
    //private static LinkedList<String> QueueSQL=new LinkedList<>();
    //List QUeueCLient
    private static List<LinkedList<String>> Queues;
    
    //luu thong tin ket noi tu client hien thoi
    private Socket clientSocket;
    
    //thread execute query from queue
    /*
    Thread executeSQL = new Thread() {
        @Override
        public void run() {
            for(int retries=0;;retries++) {
                try {
                    Class.forName("com.mysql.jdbc.Driver") ;
                    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ddm", "abc123", "Khongbiet$!@#$") ;
                    Statement stmt = conn.createStatement() ;

                    while(true) {
                        String query=QueueSQL.poll();
                        if( query == null ) {
                            try {
                                sleep(1000);
                                continue;
                            } catch (InterruptedException ex) {
                                Logger.getLogger(SyncDeamon.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        int r=stmt.executeUpdate(query);

                        //Log query statements fails, should be print to a file or a queue
                        if(r==0) {
                            System.out.println(query);
                        } 
                    }
                } catch(SQLException|ClassNotFoundException e) {
                    if (retries<3) {
                        continue;
                    } else {
                        System.out.println(e.getMessage());
                    }
                }
            }
        }
    };
    */
    
    //thread xu ly moi ket noi
    Runnable run=new Runnable(){    
            private Socket cSock;
            @Override
            public void run() {
                try {
                    cSock=clientSocket;
                    int id=IPs.indexOf(cSock.getInetAddress().getHostAddress()); //so thu tu theo IP list
                    
                    if(cSock.isClosed()) {return;}
                    if(id==-1) {
                        Logger.writeServerFile("Invalid Access : Thread " + cSock.getInetAddress().getHostAddress());
                        Logger.writeServerMonitor("Invalid Access : Thread " + cSock.getInetAddress().getHostAddress());                        
                        cSock.close();
                        return;
                    }
                    PrintWriter out =
                        new PrintWriter(cSock.getOutputStream(), true);  
                    BufferedReader in = new BufferedReader(
                        new InputStreamReader(cSock.getInputStream()));
                     String inputLine=in.readLine();
                    //client nhan data
                    switch (inputLine) {
                        case "receive":
                            String query;
                            //gui toi da 200 query tren 1 socket
                            for(int i=0;i<200;i++) {
                                query=Queues.get(id).poll();
                                if(query==null) {
                                    break;
                                }
                                out.println(query);
                            }
                            out.println("end");
                        case "send":
                            out.println("OK");
                            //server nhan data
                            int count=1;
                            while ((inputLine = in.readLine()) != null) {
                               //out.println(inputLine);
                               //read data and split to line as sql queries
                               //String data=en.decrypt(inputLine);
                               //data = en.decrypt(inputLine).split("\n");

                               //add to SQL query queue
                               //for (int i=0;i<data.length;i++) {
                               //    QueueSQL.offer(data[i]);
                               //}
                               if(inputLine.equals("end")) {
                                    break;
                                }
                               if(count>200) {
                                    break;
                                }
                               //add to Client Queues
                               for(int index=0;index<Queues.size();index++) {
                                   if (index!=id) {
                                        //for (int i=0;i<data.length;i++) {
                                        Queues.get(index).offer(inputLine);
                                        //}
                                   }
                               }
                               
                               count++;
                               //send data to other clients
                               //cList.sendData2Others(cSock.getInetAddress().getHostAddress(), inputLine);
                           }break;
                    }
                    cSock.close();
                }catch (IOException e) {
                    //System.out.println("Exception caught when trying to listen on port 6666 or listening for a connection");
                    //System.out.println(e.getMessage());
                    Logger.writeServerFile("Exception : Thread " + cSock.getInetAddress().getHostAddress()+" : "+e.toString());
                    Logger.writeServerMonitor("Exception : Thread " + cSock.getInetAddress().getHostAddress()+" : "+e.toString());
               }
            }
    };
    
    private void startServer() {
        new Thread(run).start();
    }
    
    public void startSyncDeamon(){
        try {
            //executeSQL.start();
            //init components
            IPs=Arrays.asList("1.1.1.1","2.2.2.2");
            Queues=new ArrayList();
            en=new Encrypter();
            
            ServerSocket serverSocket =new ServerSocket(port);
            for(;;) {
                clientSocket=serverSocket.accept();
                
                //allow ips in List
                //cList.addSoc(clientSocket);
                startServer();
                //don't do anything in THIS LINEs
            }
        } catch(IOException e) {
            //System.out.println(e.getMessage());
             Logger.writeServerFile("Exception : SyncDeamon " );
             Logger.writeServerMonitor("Exception : SyncDeamon " );            
        }
    }
    
    
    
}




